{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Canceling a Running Workflow\n",
    "\n",
    "You can cancel a dispatched workflow before it completes.\n",
    "\n",
    "### Prerequisites\n",
    "\n",
    "Dispatch a workflow that takes a long time to complete. During that time, you decide to cancel the workflow (perhaps because you realize you started it with the wrong parameters).\n",
    "\n",
    "The following example workflow uses the `time.sleep()` function to simulate lengthy computations:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "19971597-97b2-4e67-8224-48c71ebc0b11\n"
     ]
    }
   ],
   "source": [
    "import covalent as ct\n",
    "import time\n",
    "\n",
    "@ct.electron\n",
    "def task_1(x):\n",
    "    time.sleep(x)\n",
    "    print(\"Task 1\")\n",
    "    return x\n",
    "\n",
    "@ct.electron\n",
    "def task_2(a, b):\n",
    "    c = a + b\n",
    "    time.sleep(c)\n",
    "    print(\"Task 2\")\n",
    "    return c\n",
    "\n",
    "@ct.electron\n",
    "def task_3(a):\n",
    "    time.sleep(2)\n",
    "    print(\"Task 3\")\n",
    "    return a ** 2\n",
    "    \n",
    "@ct.lattice\n",
    "def workflow(x):\n",
    "    res_2 = task_2(task_1(10), x)\n",
    "    for _ in range(10):\n",
    "        task_1(10)\n",
    "    task_3(res_2)\n",
    "\n",
    "dispatch_id = ct.dispatch(workflow)(5)\n",
    "print(dispatch_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Procedure\n",
    "\n",
    "1. Demonstrate that the workflow is still running by executing the following within a few seconds of starting the workflow:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Lattice Result\n",
      "==============\n",
      "status: RUNNING\n",
      "result: None\n",
      "input args: ['5']\n",
      "input kwargs: {}\n",
      "error: None\n",
      "\n",
      "start_time: 2023-04-24 18:26:34.259397\n",
      "end_time: None\n",
      "\n",
      "results_dir: /home/user/.local/share/covalent/data\n",
      "dispatch_id: 19971597-97b2-4e67-8224-48c71ebc0b11\n",
      "\n",
      "Node Outputs\n",
      "------------\n",
      "task_1(0): None\n",
      ":parameter:10(1): None\n",
      "task_2(2): None\n",
      ":parameter:5(3): None\n",
      "task_1(4): None\n",
      ":parameter:10(5): None\n",
      "task_1(6): None\n",
      ":parameter:10(7): None\n",
      "task_1(8): None\n",
      ":parameter:10(9): None\n",
      "task_1(10): None\n",
      ":parameter:10(11): None\n",
      "task_1(12): None\n",
      ":parameter:10(13): None\n",
      "task_1(14): None\n",
      ":parameter:10(15): None\n",
      "task_1(16): None\n",
      ":parameter:10(17): None\n",
      "task_1(18): None\n",
      ":parameter:10(19): None\n",
      "task_1(20): None\n",
      ":parameter:10(21): None\n",
      "task_1(22): None\n",
      ":parameter:10(23): None\n",
      "task_3(24): None\n",
      ":postprocess:(25): None\n",
      "\n"
     ]
    }
   ],
   "source": [
    "time.sleep(3)\n",
    "result = ct.get_result(dispatch_id)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. Use the `ct.cancel()` function to stop the workflow:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Dispatch 19971597-97b2-4e67-8224-48c71ebc0b11 cancelled.'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ct.cancel(dispatch_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. Check the result again. Note that some of the nodes might have completed (they have returned outputs), but the lattice status is `CANCELLED`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Lattice Result\n",
      "==============\n",
      "status: CANCELLED\n",
      "result: None\n",
      "input args: ['5']\n",
      "input kwargs: {}\n",
      "error: The following tasks failed:\n",
      "\n",
      "\n",
      "start_time: 2023-04-24 18:26:34.259397\n",
      "end_time: 2023-04-24 18:26:45.612591\n",
      "\n",
      "results_dir: /home/user/.local/share/covalent/data\n",
      "dispatch_id: 19971597-97b2-4e67-8224-48c71ebc0b11\n",
      "\n",
      "Node Outputs\n",
      "------------\n",
      "task_1(0): 10\n",
      ":parameter:10(1): 10\n",
      "task_2(2): None\n",
      ":parameter:5(3): 5\n",
      "task_1(4): 10\n",
      ":parameter:10(5): 10\n",
      "task_1(6): 10\n",
      ":parameter:10(7): 10\n",
      "task_1(8): 10\n",
      ":parameter:10(9): 10\n",
      "task_1(10): 10\n",
      ":parameter:10(11): 10\n",
      "task_1(12): 10\n",
      ":parameter:10(13): 10\n",
      "task_1(14): 10\n",
      ":parameter:10(15): 10\n",
      "task_1(16): 10\n",
      ":parameter:10(17): 10\n",
      "task_1(18): 10\n",
      ":parameter:10(19): 10\n",
      "task_1(20): 10\n",
      ":parameter:10(21): 10\n",
      "task_1(22): 10\n",
      ":parameter:10(23): 10\n",
      "task_3(24): None\n",
      ":postprocess:(25): None\n",
      "\n",
      "{'task_1(0)': <covalent.TransportableObject object at 0x7f4979b191f0>, ':parameter:10(1)': <covalent.TransportableObject object at 0x7f4979b190d0>, 'task_2(2)': None, ':parameter:5(3)': <covalent.TransportableObject object at 0x7f4979b197f0>, 'task_1(4)': <covalent.TransportableObject object at 0x7f4979b19970>, ':parameter:10(5)': <covalent.TransportableObject object at 0x7f4979b19d90>, 'task_1(6)': <covalent.TransportableObject object at 0x7f4979b19b20>, ':parameter:10(7)': <covalent.TransportableObject object at 0x7f4979b19f70>, 'task_1(8)': <covalent.TransportableObject object at 0x7f4979ab91c0>, ':parameter:10(9)': <covalent.TransportableObject object at 0x7f4979ab9220>, 'task_1(10)': <covalent.TransportableObject object at 0x7f4979ab9460>, ':parameter:10(11)': <covalent.TransportableObject object at 0x7f4979ab94c0>, 'task_1(12)': <covalent.TransportableObject object at 0x7f4979ab9700>, ':parameter:10(13)': <covalent.TransportableObject object at 0x7f4979ab9760>, 'task_1(14)': <covalent.TransportableObject object at 0x7f4979ab99a0>, ':parameter:10(15)': <covalent.TransportableObject object at 0x7f4979ab9a00>, 'task_1(16)': <covalent.TransportableObject object at 0x7f4979ab9c40>, ':parameter:10(17)': <covalent.TransportableObject object at 0x7f4979ab9ca0>, 'task_1(18)': <covalent.TransportableObject object at 0x7f4979ab9ee0>, ':parameter:10(19)': <covalent.TransportableObject object at 0x7f4979ab9f40>, 'task_1(20)': <covalent.TransportableObject object at 0x7f4979ac21c0>, ':parameter:10(21)': <covalent.TransportableObject object at 0x7f4979ac2220>, 'task_1(22)': <covalent.TransportableObject object at 0x7f4979ac2460>, ':parameter:10(23)': <covalent.TransportableObject object at 0x7f4979ac24c0>, 'task_3(24)': None, ':postprocess:(25)': None}\n"
     ]
    }
   ],
   "source": [
    "result = ct.get_result(dispatch_id, wait=True)\n",
    "print(result)\n",
    "\n",
    "print(result.get_all_node_outputs())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this example, which used the default Dask executor, any tasks that were already started ran to completion because Dask does not allow cancellation of a running thread. Only nodes that had not yet begun execution were canceled.\n",
    "\n",
    "In general, how the lattice shuts down depends on the executors used by the nodes. "
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "f63e7985caea997504032bc67ebf6b6ff07db5420026db9c4de4a9a029ce747c"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
